package com.universal.frame.generalutils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;

/**
 * Desction:日期时间工具类
 * Author:pengjianbo
 * Date:15/9/17 下午4:20
 */
public class DateUtil {

    public static Date date = null;
    public static DateFormat dateFormat = null;
    public static Calendar calendar = null;

    /**
     * 静态常量
     */
    public static final String C_TIME_PATTON_DEFAULT = "yyyy-MM-dd HH:mm:ss";
    public static final String C_TIME_PATTON_DEFAULT_2 = "yyyy-MM-dd HH:mm";
    public static final String C_TIME_PATTON_DEFAULT_3 = "MM-dd HH:mm";
    public static final String C_TIME_PATTON_DEFAULT_4 = "HH:mm";
    public static final String C_TIME_PATTON_DEFAULT_5 = "HH:mm:ss";
    public static final String C_TIME_PATTON_DEFAULT_6 = "MM月dd日 HH:mm";

    public static final String C_DATE_PATTON_DEFAULT = "yyyy-MM-dd";
    public static final String C_DATE_PATTON_DEFAULT_2 = "yyyy-MM";
    public static final String C_DATE_PATTON_DEFAULT_3 = "MM-dd";
    public static final String C_DATE_PATTON_DEFAULT_4 = "MM月dd日";
    public static final String C_DATE_PATTON_DEFAULT_5 = "yyyy";

    public static final int C_ONE_SECOND = 1000;
    public static final int C_ONE_MINUTE = 60 * C_ONE_SECOND;
    public static final long C_ONE_HOUR = 60 * C_ONE_MINUTE;
    public static final long C_ONE_DAY = 24 * C_ONE_HOUR;


    /**
     * 把指定格式日期转成指定新的格式日期字符串
     *
     * @param source     例如原日期字符串：2015-04-23 11:19:30
     * @param patternOld 原日期字符串格式yyyy-MM-dd HH:mm:ss
     * @param patternNew 新的日期字符串格式yyyyMMddHHmmss
     * @return 返回格式为20150423111930或null
     */
    public static String getDate(String source, String patternOld, String patternNew) {
        String newDateStr = null;
        try {
            newDateStr = new SimpleDateFormat(patternNew).format(new SimpleDateFormat(patternOld).parse(source))
                    .toString();
            ;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return newDateStr;
    }

    /**
     * 根据时间戳返回日期时间
     **/
    public static String starmpToData(String starmp) {
        if (null != starmp) {
            Long time = Long.parseLong(starmp);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String sd = sdf.format(new Date(Long.parseLong(String.valueOf(time))));
            return sd;
        }
        return "";
    }

    public static String stringToData(String starmp) {
        if (null != starmp) {
            Long time = Long.parseLong(starmp);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String sd = sdf.format(new Date(Long.parseLong(String.valueOf(time))));
            return sd;
        }
        return "";
    }


    /**
     * 功能描述：格式化输出日期
     *
     * @param date   Date 日期
     * @param format String 格式
     * @return 返回字符型日期
     */
    public static String format(Date date, String format) {
        String result = "";
        try {
            if (date != null) {
                dateFormat = new SimpleDateFormat(format);
                result = dateFormat.format(date);
            }
        } catch (Exception e) {
        }
        return result;
    }


    /**
     * 功能描述：返回年份
     *
     * @param date Date 日期
     */
    public static int getYear(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.YEAR);
    }

    /**
     * 功能描述：返回月份
     */
    public static int getMonth(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH) + 1;
    }

    /**
     * 功能描述：返回日
     */
    public static int getDay(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    //时间戳装换成Date
    public static Date orData(Long time) throws ParseException {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String d = format.format(time);
        Date date = format.parse(d);
        return date;
    }

    /**
     * 功能描述：返回小时
     */
    public static int getHour(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 功能描述：返回分钟
     */
    public static int getMinute(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MINUTE);
    }

    /**
     * 返回秒钟
     */
    public static int getSecond(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.SECOND);
    }

    /**
     * 功能描述：返回毫秒
     *
     * @param date 日期
     * @return 返回毫秒
     */
    public static long getMillis(Date date) {
        calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取当前年或月或日
     * @return
     */
    public static int getSingleDay(){
        final Calendar ca = Calendar.getInstance();
        int mYear = ca.get(Calendar.YEAR);
        int mMonth = ca.get(Calendar.MONTH);
        int mDay = ca.get(Calendar.DAY_OF_MONTH);
        return mDay;
    }

    /**
     * 功能描述：日期相加
     *
     * @param date Date 日期
     * @param day  int 天数
     * @return 返回相加后的日期
     */
    public static Date addDate(Date date, int day) {
        calendar = Calendar.getInstance();
        long millis = getMillis(date) + ((long) day) * 24 * 3600 * 1000;
        calendar.setTimeInMillis(millis);
        return calendar.getTime();
    }

    /**
     * 功能描述：日期相减
     *
     * @param date  Date 日期
     * @param date1 Date 日期
     * @return 返回相减后的日期
     */
    public static int diffDate(Date date, Date date1) {
        return (int) ((getMillis(date) - getMillis(date1)) / (24 * 3600 * 1000));
    }

    /**
     * 功能描述：常用的格式化日期
     *
     * @param date Date 日期
     * @return String 日期字符串 yyyy-MM-dd格式
     */
    public static String formatDate(Date date) {
        return formatDateByFormat(date, "yyyy-MM-dd");
    }

    /**
     * 功能描述：以指定的格式来格式化日期
     *
     * @param date   Date 日期
     * @param format String 格式
     * @return String 日期字符串
     */
    public static String formatDateByFormat(Date date, String format) {
        String result = "";
        if (date != null) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(format);
                result = sdf.format(date);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    /**
     * 获取某天是星期几
     *
     * @param date
     * @return
     */
    public static String getMonthDayWeek(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int year = c.get(Calendar.YEAR);    //获取年
        int month = c.get(Calendar.MONTH) + 1;   //获取月份，0表示1月份
        int day = c.get(Calendar.DAY_OF_MONTH);    //获取当前天数
        int week = c.get(Calendar.DAY_OF_WEEK);

        String weekStr = null;

        switch (week) {

            case Calendar.SUNDAY:
                weekStr = "周日";
                break;

            case Calendar.MONDAY:
                weekStr = "周一";
                break;

            case Calendar.TUESDAY:
                weekStr = "周二";
                break;

            case Calendar.WEDNESDAY:
                weekStr = "周三";
                break;

            case Calendar.THURSDAY:
                weekStr = "周四";
                break;

            case Calendar.FRIDAY:
                weekStr = "周五";
                break;

            case Calendar.SATURDAY:
                weekStr = "周六";
                break;
        }

        return month + "月" + day + "日" + "(" + weekStr + ")";
    }

    /**
     * 日期字符串转换为日期
     *
     * @param date    日期字符串
     * @param pattern 格式
     * @return 日期
     */
    public static Date formatStringByFormat(String date, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return sdf.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 获得口头时间字符串，如今天，昨天等
     *
     * @param d 时间格式为yyyy-MM-dd HH:mm:ss
     * @return 口头时间字符串
     */
    public static String getTimeInterval(String d) {
        Date date = formatStringByFormat(d, "yyyy-MM-dd HH:mm:ss");
        Calendar now = Calendar.getInstance();
        now.setTime(new Date());
        int nowYear = now.get(Calendar.YEAR);
        int nowMonth = now.get(Calendar.MONTH);
        int nowWeek = now.get(Calendar.WEEK_OF_MONTH);
        int nowDay = now.get(Calendar.DAY_OF_WEEK);
        int nowHour = now.get(Calendar.HOUR_OF_DAY);
        int nowMinute = now.get(Calendar.MINUTE);

        Calendar ca = Calendar.getInstance();
        if (date != null)
            ca.setTime(date);
        else
            ca.setTime(new Date());
        int year = ca.get(Calendar.YEAR);
        int month = ca.get(Calendar.MONTH);
        int week = ca.get(Calendar.WEEK_OF_MONTH);
        int day = ca.get(Calendar.DAY_OF_WEEK);
        int hour = ca.get(Calendar.HOUR_OF_DAY);
        int minute = ca.get(Calendar.MINUTE);
        if (year != nowYear) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            //不同年份
            return sdf.format(date);
        } else {
            if (month != nowMonth) {
                //不同月份
                SimpleDateFormat sdf = new SimpleDateFormat("M月dd日");
                return sdf.format(date);
            } else {
                if (week != nowWeek) {
                    //不同周
                    SimpleDateFormat sdf = new SimpleDateFormat("M月dd日");
                    return sdf.format(date);
                } else if (day != nowDay) {
                    if (day + 1 == nowDay) {
                        return "昨天" + formatDateByFormat(date, "HH:mm");
                    }
                    if (day + 2 == nowDay) {
                        return "前天" + formatDateByFormat(date, "HH:mm");
                    }
                    //不同天
                    SimpleDateFormat sdf = new SimpleDateFormat("M月dd日");
                    return sdf.format(date);
                } else {
                    //同一天
                    int hourGap = nowHour - hour;
                    if (hourGap == 0)//1小时内
                    {
                        if (nowMinute - minute < 1) {
                            return "刚刚";
                        } else {
                            return (nowMinute - minute) + "分钟前";
                        }
                    } else if (hourGap >= 1 && hourGap <= 12) {
                        return hourGap + "小时前";
                    } else {
                        SimpleDateFormat sdf = new SimpleDateFormat("今天 HH:mm");
                        return sdf.format(date);
                    }
                }
            }
        }
    }

    /**
     * 日期字符串转换为日期
     *
     * @param date    日期字符串
     * @param pattern 格式
     * @return 日期
     */
    public static String reformatTime(String date, String pattern) {
        String fmt = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simple = new SimpleDateFormat(pattern);
        Date old = parseToDate(date, fmt);
        return simple.format(old);
    }

    /**
     * 字符串转换成日期.
     *
     * @param dateString 日期字符
     * @param pattern    格式化.
     * @return
     */
    public static Date parseToDate(String dateString, String pattern) {

        if (pattern == null || "".equals(pattern)) {
            pattern = "yyyy-MM-dd HH:mm:ss";
        }

        SimpleDateFormat formatter = new SimpleDateFormat(pattern, Locale.getDefault());
        try {
            return formatter.parse(dateString);
        } catch (ParseException e) {

        }
        return new Date();
    }

    /***
     * 获取当前时间
     *
     * @return
     */
    public static String getTime() {
        return new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance()
                .getTime());
    }

    /***
     * 获取当前日期
     *
     * @return
     */
    public static String getDate() {
        return new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance()
                .getTime());
    }

    public static String getDate(String format) {
        return new SimpleDateFormat(format).format(Calendar.getInstance()
                .getTime());
    }

    public static String parseWithDate(String time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = sdf.parse(time);
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy年MM月dd日");
            return sdf2.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String parseWithDate(String format1, String format2, String time) {
        SimpleDateFormat sdf = new SimpleDateFormat(format1);
        try {
            Date date = sdf.parse(time);
            SimpleDateFormat sdf2 = new SimpleDateFormat(format2);
            return sdf2.format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /***
     * 获取当前时间
     *
     * @return
     */
    public static String getCurrentTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar
                .getInstance().getTime());
    }

    public static String getCurrentTime2() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm").format(Calendar
                .getInstance().getTime());
    }

    /**
     * 计算当前月份的最大天数
     *
     * @return
     */
    public static int findMaxDayInMonth() {
        return findMaxDayInMonth(0, 0);
    }

    /**
     * 计算指定日期月份的最大天数
     *
     * @param date
     * @return
     */
    public static int findMaxDayInMonth(Date date) {
        if (date == null) {
            return 0;
        }
        return findMaxDayInMonth(date2Calendar(date));
    }

    /**
     * 计算指定日历月份的最大天数
     *
     * @param calendar
     * @return
     */
    public static int findMaxDayInMonth(Calendar calendar) {
        if (calendar == null) {
            return 0;
        }

        return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 计算当前年某月份的最大天数
     *
     * @param month
     * @return
     */
    public static int findMaxDayInMonth(int month) {
        return findMaxDayInMonth(0, month);
    }

    /**
     * 计算某年某月份的最大天数
     *
     * @param year
     * @param month
     * @return
     */
    public static int findMaxDayInMonth(int year, int month) {
        Calendar calendar = Calendar.getInstance();
        if (year > 0) {
            calendar.set(Calendar.YEAR, year);
        }

        if (month > 0) {
            calendar.set(Calendar.MONTH, month - 1);
        }

        return findMaxDayInMonth(calendar);
    }

    /**
     * Calendar 转换为 Date
     *
     * @param calendar
     * @return
     */
    public static Date calendar2Date(Calendar calendar) {
        if (calendar == null) {
            return null;
        }
        return calendar.getTime();
    }

    /**
     * Date 转换为 Calendar
     *
     * @param date
     * @return
     */
    public static Calendar date2Calendar(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 拿到默认格式的SimpleDateFormat
     *
     * @return
     */
    public static SimpleDateFormat getSimpleDateFormat() {
        return getSimpleDateFormat(null);
    }

    /**
     * 拿到指定输出格式的SimpleDateFormat
     *
     * @param format
     * @return
     */
    public static SimpleDateFormat getSimpleDateFormat(String format) {
        SimpleDateFormat sdf;
        if (format == null) {
            sdf = new SimpleDateFormat(C_TIME_PATTON_DEFAULT);
        } else {
            sdf = new SimpleDateFormat(format);
        }

        return sdf;
    }

    /**
     * 转换当前时间为默认格式
     *
     * @return
     */
    public static String formatDate2Str() {
        return formatDate2Str(new Date());
    }

    /**
     * 转换指定时间为默认格式
     *
     * @param date
     * @return
     */
    public static String formatDate2Str(Date date) {
        return formatDate2Str(date, C_TIME_PATTON_DEFAULT);
    }

    /**
     * 转换指定时间为指定格式
     *
     * @param date
     * @param format
     * @return
     */
    public static String formatDate2Str(Date date, String format) {
        if (date == null) {
            return null;
        }

        if (format == null || format.equals("")) {
            format = C_TIME_PATTON_DEFAULT;
        }
        SimpleDateFormat sdf = getSimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 转换默认格式的时间为Date
     *
     * @param dateStr
     * @return
     */
    public static Date formatStr2Date(String dateStr) {
        return formatStr2Date(dateStr, null);
    }

    /**
     * 转换指定格式的时间为Date
     *
     * @param dateStr
     * @param format
     * @return
     */
    public static Date formatStr2Date(String dateStr, String format) {
        if (dateStr == null) {
            return null;
        }

        if (format == null || format.equals("")) {
            format = C_TIME_PATTON_DEFAULT;
        }
        SimpleDateFormat sdf = getSimpleDateFormat(format);
        return sdf.parse(dateStr, new ParsePosition(0));
    }

    /**
     * 转换默认格式的时间为指定格式时间
     *
     * @param dateStr
     * @param defineFormat
     * @return
     */
    public static String formatDefault2Define(String dateStr,
                                              String defineFormat) {
        return formatSource2Target(dateStr, C_TIME_PATTON_DEFAULT, defineFormat);
    }

    /**
     * 转换源格式的时间为目标格式时间
     *
     * @param dateStr
     * @param sourceFormat
     * @param targetFormat
     * @return
     */
    public static String formatSource2Target(String dateStr,
                                             String sourceFormat, String targetFormat) {
        Date date = formatStr2Date(dateStr, sourceFormat);
        return formatDate2Str(date, targetFormat);
    }

    /**
     * 计算当天是该年中的第几周
     *
     * @return
     */
    public static int findWeeksNoInYear() {
        return findWeeksNoInYear(new Date());
    }

    /**
     * 计算指定日期是该年中的第几周
     *
     * @param date
     * @return
     */
    public static int findWeeksNoInYear(Date date) {
        if (date == null) {
            return 0;
        }
        return findWeeksNoInYear(date2Calendar(date));
    }

    /**
     * 计算指定日历是该年中的第几周
     *
     * @param calendar
     * @return
     */
    public static int findWeeksNoInYear(Calendar calendar) {
        if (calendar == null) {
            return 0;
        }
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    public static String getTomorrowDate() {
        Date date = new Date();// 取时间
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.add(calendar.DATE, 1);// 把日期往后增加一天.整数往后推,负数往前移动
        date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(date);
        return dateString;
    }

    /**
     * 计算一年中的第几星期是几号
     *
     * @param year
     * @param weekInYear
     * @param dayInWeek
     * @return
     */
    public static Date findDateInWeekOnYear(int year, int weekInYear,
                                            int dayInWeek) {
        Calendar calendar = Calendar.getInstance();
        if (year > 0) {
            calendar.set(Calendar.YEAR, year);
        }

        calendar.set(Calendar.WEEK_OF_YEAR, weekInYear);
        calendar.set(Calendar.DAY_OF_WEEK, dayInWeek);

        return calendar.getTime();
    }

    /**
     * 相对于当前日期的前几天(days < 0０００００)或者后几天(days > 0)
     *
     * @param days
     * @return
     */
    public static Date dayBefore2Date(int days) {
        Date date = new Date();
        return dayBefore2Object(days, null, date);
    }

    /**
     * 相对于当前日期的前几天(days < 0０００００)或者后几天(days > 0)
     *
     * @param days
     * @return
     */
    public static String dayBefore2Str(int days) {
        String string = formatDate2Str();
        return dayBefore2Object(days, null, string);
    }

    /**
     * 相对于当前日期的前几天(days < 0０００００)或者后几天(days > 0)
     *
     * @param days
     * @param format
     * @param instance
     */
    @SuppressWarnings("unchecked")
    public static <T extends Object> T dayBefore2Object(int days,
                                                        String format, T instance) {
        Calendar calendar = Calendar.getInstance();
        if (days == 0) {
            return null;
        }

        if (format == null || format.equals("")) {
            format = C_TIME_PATTON_DEFAULT;
        }

        calendar.add(Calendar.DATE, days);
        if (instance instanceof Date) {
            return (T) calendar.getTime();
        } else if (instance instanceof String) {
            return (T) formatDate2Str(calendar2Date(calendar), format);
        }
        return null;
    }

    /**
     * 相对于指定日期的前几天(days < 0０００００)或者后几天(days > 0)
     *
     * @param date
     * @param days
     * @return
     */
    public static Date defineDayBefore2Date(Date date, int days) {
        Date dateInstance = new Date();
        return defineDayBefore2Object(date, days, null, dateInstance);
    }

    /**
     * 相对于指定日期的前几天(days < 0０００００)或者后几天(days > 0)
     *
     * @param date
     * @param days
     * @return
     */
    public static String defineDayBefore2Str(Date date, int days) {
        String stringInstance = formatDate2Str();
        return defineDayBefore2Object(date, days, null, stringInstance);
    }

    /**
     * 相对于指定日期的前几天(days < 0０００００)或者后几天(days > 0)
     *
     * @param <T>
     * @param date
     * @param days
     * @param format
     * @param instance
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T extends Object> T defineDayBefore2Object(Date date,
                                                              int days, String format, T instance) {
        if (date == null || days == 0) {
            return null;
        }

        if (format == null || format.equals("")) {
            format = C_TIME_PATTON_DEFAULT;
        }

        Calendar calendar = date2Calendar(date);
        calendar.add(Calendar.DATE, days);
        if (instance instanceof Date) {
            return (T) calendar.getTime();
        } else if (instance instanceof String) {
            return (T) formatDate2Str(calendar2Date(calendar), format);
        }
        return null;
    }

    /**
     * 相对于当前日期的前几月(months < 0０００００)或者后几月(months > 0)时间
     *
     * @param months
     * @return
     */
    public static Date monthBefore2Date(int months) {
        Date date = new Date();
        return monthBefore2Object(months, null, date);
    }

    /**
     * 相对于当前日期的前几月(months < 0０００００)或者后几月(months > 0)时间
     *
     * @param months
     * @return
     */
    public static String monthBefore2Str(int months) {
        String string = formatDate2Str();
        return monthBefore2Object(months, null, string);
    }

    /**
     * 相对于当前日期的前几月(months < 0０００００)或者后几月(months > 0)时间
     *
     * @param <T>
     * @param months
     * @param format
     * @param instance
     */
    @SuppressWarnings("unchecked")
    public static <T extends Object> T monthBefore2Object(int months,
                                                          String format, T instance) {
        if (months == 0) {
            return null;
        }

        if (format == null || format.equals("")) {
            format = C_TIME_PATTON_DEFAULT;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, months);

        if (instance instanceof Date) {
            return (T) calendar.getTime();
        } else if (instance instanceof String) {
            return (T) formatDate2Str(calendar2Date(calendar), format);
        }

        return null;
    }

    /**
     * 相对于指定日期的前几月(months < 0０００００)或者后几月(months > 0)时间
     *
     * @param date
     * @param months
     * @return
     */
    public static Date defineMonthBefore2Date(Date date, int months) {
        Date dateInstance = new Date();
        return defineMonthBefore2Object(date, months, null, dateInstance);
    }

    /**
     * 相对于指定日期的前几月(months < 0０００００)或者后几月(months > 0)时间
     *
     * @param date
     * @param months
     * @return
     */
    public static String defineMonthBefore2Str(Date date, int months) {
        String stringInstance = formatDate2Str();
        return defineMonthBefore2Object(date, months, null, stringInstance);
    }

    /**
     * 相对于指定日期的前几月(months < 0０００００)或者后几月(months > 0)时间
     *
     * @param <T>
     * @param date
     * @param months
     * @param format
     * @param instance
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T extends Object> T defineMonthBefore2Object(Date date,
                                                                int months, String format, T instance) {
        if (months == 0) {
            return null;
        }

        if (format == null || format.equals("")) {
            format = C_TIME_PATTON_DEFAULT;
        }

        Calendar calendar = date2Calendar(date);
        calendar.add(Calendar.MONTH, months);

        if (instance instanceof Date) {
            return (T) calendar.getTime();
        } else if (instance instanceof String) {
            return (T) formatDate2Str(calendar2Date(calendar), format);
        }

        return null;
    }

    /**
     * 计算两个日期直接差的天数
     *
     * @param firstDate
     * @param secondDate
     * @return
     */
    public static int caculate2Days(Date firstDate, Date secondDate) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(firstDate);
        int dayNum1 = calendar.get(Calendar.DAY_OF_YEAR);
        calendar.setTime(secondDate);
        int dayNum2 = calendar.get(Calendar.DAY_OF_YEAR);
        return Math.abs(dayNum1 - dayNum2);
    }

    /**
     * 计算两个日期直接差的天数
     *
     * @param firstCalendar
     * @param secondCalendar
     * @return
     */
    public static int caculate2Days(Calendar firstCalendar,
                                    Calendar secondCalendar) {
        if (firstCalendar.after(secondCalendar)) {
            Calendar calendar = firstCalendar;
            firstCalendar = secondCalendar;
            secondCalendar = calendar;
        }

        long calendarNum1 = firstCalendar.getTimeInMillis();
        long calendarNum2 = secondCalendar.getTimeInMillis();
        return Math.abs((int) ((calendarNum1 - calendarNum2) / C_ONE_DAY));
    }

    public static void main(String[] args) {
        // System.out.println("当前月份的最大天数:" + findMaxDayInMonth(new Date()));
        // System.out.println("6月份的最大天数:" + findMaxDayInMonth(6));
        // System.out.println("1999-02月份的最大天数:" + findMaxDayInMonth(1999, 2));
        // System.out.println("2000-02月份的最大天数:" + findMaxDayInMonth(2000, 2));

        // System.out.println(formatSource2Target("2009-07-24 11:02:35", null,
        // "yyyy/MM/dd"));
        // System.out.println(findWeeksNoInYear());

        // System.out.println("2003年的第30个星期一是那天:" + findDateInWeekOnYear(2003,
        // 30, Calendar.MONDAY));
        // System.out.println("2009年的第30个星期一是那天:" + findDateInWeekOnYear(2009,
        // 30, Calendar.FRIDAY));

        // System.out.println("【日期格式】当前日期的前7天是:" + dayBefore2Date(-7));
        // System.out.println("【字符格式】当前日期的前7天是:" + dayBefore2Str(-7));
        // System.out.println("【日期格式】当前日期的后7天是:" + dayBefore2Date(7));
        // System.out.println("【字符格式】当前日期的后7天是:" + dayBefore2Str(7));

        // System.out.println(formatStr2Date("2009-07-22", "yyyy-MM-dd"));

        // System.out.println("【日期格式】2009-07-22的前7天是:" +
        // defineDayBefore2Date(formatStr2Date("2009-07-22", "yyyy-MM-dd"),
        // -7));
        // System.out.println("【字符格式】2009-07-22的前7天是:" +
        // defineDayBefore2Str(formatStr2Date("2009-07-22", "yyyy-MM-dd"), -7));
        // System.out.println("【日期格式】2009-07-22的后7天是:" +
        // defineDayBefore2Date(formatStr2Date("2009-07-22", "yyyy-MM-dd"), 7));
        // System.out.println("【字符格式】2009-07-22的后7天是:" +
        // defineDayBefore2Str(formatStr2Date("2009-07-22", "yyyy-MM-dd"), 7));

        // System.out.println("【日期格式】相对于当前时间的前2月日期是:" + monthBefore2Date(-2));
        // System.out.println("【字符格式】相对于当前时间的前2月日期是:" + monthBefore2Date(-2));
        // System.out.println("【日期格式】相对于当前时间的后2月日期是:" + monthBefore2Date(2));
        // System.out.println("【字符格式】相对于当前时间的后2月日期是:" + monthBefore2Date(2));

        // System.out.println("【日期格式】2009-07-22的前2月日期是:" +
        // defineMonthBefore2Date(formatStr2Date("2009-07-22", "yyyy-MM-dd"),
        // -2));
        // System.out.println("【字符格式】2009-07-22的前2月日期是:" +
        // defineMonthBefore2Date(formatStr2Date("2009-07-22", "yyyy-MM-dd"),
        // -2));
        // System.out.println("【日期格式】2009-07-22的后2月日期是:" +
        // defineMonthBefore2Date(formatStr2Date("2009-07-22", "yyyy-MM-dd"),
        // 2));
        // System.out.println("【字符格式】2009-07-22的后2月日期是:" +
        // defineMonthBefore2Date(formatStr2Date("2009-07-22", "yyyy-MM-dd"),
        // 2));

        // Date firstDate = formatStr2Date("2009-07-22", "yyyy-MM-dd");
        // Date secondDate = formatStr2Date("2009-07-18", "yyyy-MM-dd");
        // System.out.println(caculate2Days(firstDate, secondDate));

        // Calendar firstC = date2Calendar(formatStr2Date("2009-07-22",
        // "yyyy-MM-dd"));
        // Calendar secondC = date2Calendar(formatStr2Date("2009-07-18",
        // "yyyy-MM-dd"));
        // System.out.println(caculate2Days(firstC, secondC));

        System.out.println(getWeekDay(123));

    }

    /**
     * 计算两个日期相差多少天 函数功能说明 修改者名字 修改日期 修改内容
     *
     * @param startDate
     * @param endDate
     * @return long
     * @author wanxianze@gmail.com 2013-5-29
     */
    public static long diffDays(Date startDate, Date endDate) {
        long diff = startDate.getTime() - endDate.getTime();
        return diff / (1000L * 60L * 60L * 24L);
    }

    /**
     * 计算两个日期相差多少天 函数功能说明 修改者名字 修改日期 修改内容
     *
     * @param startDate
     * @param endDate
     * @return long
     * @author wanxianze@gmail.com 2013-5-29
     */
    public static long diffYears(Date startDate, Date endDate) {
        long diff = startDate.getTime() - endDate.getTime();
        return diff / (1000L * 60L * 60L * 24L * 360L);
    }

    /**
     * 取得当前日期是多少周
     *
     * @param date
     * @return
     */
    public static int getWeekOfYear(Calendar calendar) {
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setMinimalDaysInFirstWeek(7);
        return calendar.get(Calendar.WEEK_OF_YEAR);
    }

    /**
     * @param date
     * @return
     */
    public static String toDateString(Date date) {

        String result = "";
        Calendar curCalendar = Calendar.getInstance();
        Calendar anotherCalendar = Calendar.getInstance();
        anotherCalendar.setTime(date);
        // 同一年
        if (curCalendar.get(Calendar.YEAR) == anotherCalendar
                .get(Calendar.YEAR)) {
            int days = curCalendar.get(Calendar.DAY_OF_YEAR)
                    - anotherCalendar.get(Calendar.DAY_OF_YEAR);
            // 同一周
            if (getWeekOfYear(curCalendar) == getWeekOfYear(anotherCalendar)) {
                if (days < 3) {// 三天内
                    if (days == 0) {
                        return result = toTimeString(anotherCalendar, true);
                    } else if (days == 1) {
                        return result = "昨天"
                                + toTimeString(anotherCalendar, false);
                    } else if (days == 2) {
                        return result = "前天"
                                + toTimeString(anotherCalendar, false);
                    }
                } else {
                    return toWeekDay(anotherCalendar)
                            + toTimeString(anotherCalendar, false);
                }
            } else {
                return result = formatDate2Str(anotherCalendar.getTime(),
                        "M月d日");
            }

        } else
            return result = formatDate2Str();
        return result;

    }

    public static String toTimeString(Calendar c, boolean addTime) {
        int hour = c.get(Calendar.HOUR_OF_DAY);
        String time = addTime ? formatDate2Str(c.getTime(), "HH:mm") : "";
        if (hour < 4) {
            return "凌晨" + time;
        } else if (hour <= 9)
            return "早上" + time;
        if (hour <= 11)
            return "上午" + time;
        else if (hour == 12)
            return "中午" + time;
        else if (hour <= 18)
            return "下午" + time;
        else
            return "晚上" + time;

    }

    /**
     * 获取星期几
     *
     * @return
     */
    public static String toWeekDay(Calendar c) {
        int dayFlag = c.get(Calendar.DAY_OF_WEEK);
        switch (dayFlag) {
            case 1:
                return "星期天";
            case 2:
                return "星期一";
            case 3:
                return "星期二";
            case 4:
                return "星期三";
            case 5:
                return "星期四";
            case 6:
                return "星期五";
            case 7:
                return "星期六";
            default:
                return null;
        }
    }

    /**
     * 获取星期几
     *
     * @param afterOrBefore 如果是今天为0，前一天-1，后一天1
     * @return
     */
    @SuppressWarnings("unused")
    public static String getWeekDay(int afterOrBefore) {
        Date requestDate = new Date();
        if (afterOrBefore != 0) {
            requestDate = dayBefore2Date(afterOrBefore);
        }
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH, 1);
        // DateUtils.date2Calendar(requestDate);
        // System.out.println(requestDate);
        int dayFlag = c.get(Calendar.DAY_OF_WEEK);
        switch (dayFlag) {
            case 1:
                return "星期天";
            case 2:
                return "星期一";
            case 3:
                return "星期二";
            case 4:
                return "星期三";
            case 5:
                return "星期四";
            case 6:
                return "星期五";
            case 7:
                return "星期六";
            default:
                return null;
        }
    }


    /**
     * 将短时间格式时间转换为字符串 yyyy-MM-dd
     *
     * @param dateDate
     * @param k
     * @return
     */
    public static String dateToStr(java.util.Date dateDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(dateDate);
        return dateString;
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd
     *
     * @param strDate
     * @return
     */
    public static Date strToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

}
